package com.yequan.exe.core;

import com.yequan.pojo.CalcData;
import com.yequan.pojo.ExeInfo;

import java.io.*;

/**
 * @author yq
 * @date 2020/09/29
 */
public class ProcessExecutor {

    private CalcData calcData;

    private LogOutListener logOutListener;

    public ProcessExecutor(CalcData calcData, LogOutListener logOutListener) {
        this.calcData = calcData;
        this.logOutListener = logOutListener;
    }

    public int execute() {
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        ExeInfo exeInfo = calcData.getExeInfo();
        StringBuilder logCache = null;
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(exeInfo.getCommand());
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            inputStream = process.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "GBK");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line = null;
            logCache = new StringBuilder();
            while ((line = bufferedReader.readLine()) != null) {
                logCache.append(line + "\r\n");
                if (exeInfo.isLogPrintable()) {
                    logOutListener.doSendLog(line);
                }
            }
            int result = process.exitValue();
            process.destroy();
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (exeInfo.isLogWritable() && (null != logCache && logCache.length() > 0)) {
                writeLog(logCache, exeInfo);
                logCache.delete(0, logCache.length());
            }
            try {
                if (null != bufferedReader) {
                    bufferedReader.close();
                }
                if (null != inputStreamReader) {
                    inputStreamReader.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 1;
    }

    private void writeLog(StringBuilder logCache, ExeInfo exeInfo) {
        FileOutputStream fileOutputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            fileOutputStream = new FileOutputStream(exeInfo.getLogPath());
            outputStreamWriter = new OutputStreamWriter(fileOutputStream);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            bufferedWriter.write(logCache.toString());
            bufferedWriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != bufferedWriter) {
                    bufferedWriter.close();
                }
                if (null != outputStreamWriter) {
                    outputStreamWriter.close();
                }
                if (null != fileOutputStream) {
                    fileOutputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
